package cn.caplike.demo.spring.security.quickstart.configuration;

import cn.caplike.demo.spring.security.quickstart.handler.CustomAuthenticationFailureHandler;
import cn.caplike.demo.spring.security.quickstart.handler.CustomSimpleUrlAuthenticationSuccessHandler;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;

/**
 * Spring security config
 *
 * @author LiKe
 * @version 1.0.0
 * @date 2020-04-15 13:15
 */
@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    private CustomAuthenticationFailureHandler customAuthenticationFailureHandler;

    private CustomSimpleUrlAuthenticationSuccessHandler customSimpleUrlAuthenticationSuccessHandler;

    private PasswordEncoder passwordEncoder;

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        // Java 配置用户名 / 密码
        auth.inMemoryAuthentication()
                .withUser("caplike").roles("ADMIN").password(passwordEncoder.encode("caplike"))
                .and()
                .withUser("tiantian").roles("USER").password(passwordEncoder.encode("tiantian"));
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        // 任何 URL 均由认证过的用户访问
        http.authorizeRequests().anyRequest().authenticated()
                .and().httpBasic()
                .and().formLogin().failureHandler(customAuthenticationFailureHandler).successHandler(customSimpleUrlAuthenticationSuccessHandler)
                // Cross Site Request Forgery: 跨站请求伪造; Reference: https://docs.spring.io/spring-security/site/docs/3.2.0.CI-SNAPSHOT/reference/html/csrf.html
                // Reference: demo-spring-security-csrf
                .and().csrf().disable()
        ;
    }

    @Bean
    PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }

    // ~Autowired
    // -----------------------------------------------------------------------------------------------------------------

    @Autowired
    public void setPasswordEncoder(PasswordEncoder passwordEncoder) {
        this.passwordEncoder = passwordEncoder;
    }

    @Autowired
    public void setCustomAuthenticationFailureHandler(CustomAuthenticationFailureHandler customAuthenticationFailureHandler) {
        this.customAuthenticationFailureHandler = customAuthenticationFailureHandler;
    }

    @Autowired
    public void setCustomSimpleUrlAuthenticationSuccessHandler(CustomSimpleUrlAuthenticationSuccessHandler customSimpleUrlAuthenticationSuccessHandler) {
        this.customSimpleUrlAuthenticationSuccessHandler = customSimpleUrlAuthenticationSuccessHandler;
    }
}
